import Obj3D from '../Poly2/Obj3D.js';
import Scene from '../Poly2/Scene.js';
import Arc from './Arc-ba.js';
import Particle from './Particle-ba.js';
import Round from './Round-ba.js';
import { Vector3 } from '../three.module.js';
import { CreateProgram } from '../Utils.js';

import Arcvert from './shader/Arc.vert.js'
import Arcfrag from './shader/Arc.frag.js'
import Particlevert from './shader/Particle.vert.js'
import Particlefrag from './shader/Particle.frag.js'
import Roundvert from './shader/Round.vert.js'
import Roundfrag from './shader/Round.frag.js'

const defAttr = () => ({
    canvas: null,

    pointSize: 35,//整体的大小
    background_color: [0, 0, 0, 0],//背景颜色

    arc_color_on: [1, 1, 1, 0.5],//弧线内颜色
    arc_color_out: [0.30, 0.53, 1, 0.5],//弧线外颜色

    particle_color: [0.5, 1, 1, 0.5],//三角粒子颜色
    particle_count: 7,//每次触发的粒子数量
    particle_diff: [0.1, 0.1],//粒子生成时离中心点的距离 / 粒子向外扩散的距离

    round_color: [0.30, 0.53, 1, 0.5],//内圆颜色
});

//圆弧
export default class baClickEffect {
    constructor(attr) {
        Object.assign(this, defAttr(), attr);

        this.gl = null;
        this.scene = null;
        this.arc = null;
        this.particle = null;
        this.round = null;

        this.dataArr = [];

        this._init();
    }

    _init() {
        this._createObject();
    }

    //point:数组对象,[x, y]
    Trigger(point) {
        const [x, y] = this._getViewPosi(point[0], point[1]);
        this._createClickEffect(new Vector3(x, y, 0));
    }

    update() {
        const { dataArr } = this;

        for (let i = 0; i < dataArr.length; i++) {
            let { set, s, effectObj, } = dataArr[i];

            if (set > 1) {
                //删除
                this._deleteData(i);
                i--;
                continue;
            }
            dataArr[i].set += s;
            effectObj.setUniform('u_Set', { value: dataArr[i].set });
        }
        this._draw();
    }

    _createObject() {
        const { canvas } = this;
        this.gl = canvas.getContext("webgl", { antialias: true, });
        const { gl } = this;
        gl.enable(gl.BLEND);
        gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

        this.scene = new Scene({ gl: gl });
        const { scene } = this;
        scene.regProgram('arc', {
            program: CreateProgram(gl,
                Arcvert.getShader(),
                Arcfrag.getShader()),
            attribs: ['a_Position'],
            uniforms: ['u_Angle', 'u_Set', 'u_PointSize', 'u_Line', 'u_line_Color',]
        });
        scene.regProgram('particle', {
            program: CreateProgram(gl,
                Particlevert.getShader(),
                Particlefrag.getShader()),
            attribs: ['a_Position'],
            uniforms: ['u_Opaque', 'u_PointSize', 'u_Angle', 'u_Color', 'u_Set', 'u_Diff', 'u_PosiMove', 'u_Color']
        });
        scene.regProgram('round', {
            program: CreateProgram(gl,
                Roundvert.getShader(),
                Roundfrag.getShader()),
            attribs: ['a_Position'],
            uniforms: ['u_PointSize', 'u_Color', 'u_Set', 'u_Margin']
        });

        const {
            pointSize,
            arc_color_on, arc_color_out,
            round_color,
            particle_color, particle_count, particle_diff,
        } = this;
        this.arc = new Arc({
            gl: gl,
            program: 'arc',
            pointSize: pointSize,
            color1: arc_color_out,
            color2: arc_color_on,
        });
        this.particle = new Particle({
            program: 'particle',
            gl: gl,
            count: particle_count,
            diff: particle_diff,
            color: particle_color,
        });
        this.round = new Round({
            program: 'round',
            gl: gl,
            pointSize: this.arc.pointSize,
            margin: this.arc.getInsideArcMargin(),
            color: round_color,
        });
    }

    _createClickEffect(point) {
        const { dataArr, scene, gl, arc, particle, round } = this;

        const effect = new Obj3D();
        const arcObj = arc.getElement(point);
        effect.add(gl, arcObj);

        const particleObj = particle.getElement(point);
        effect.add(gl, particleObj);

        const roundObj = round.getElement(point);
        effect.add(gl, roundObj);


        scene.add(effect);
        dataArr.push({
            set: 0,
            s: 0.01,
            effectObj: effect,
        });
    }

    _deleteData(index) {
        const { dataArr, scene } = this;
        const { effectObj } = dataArr[index];
        scene.remove(effectObj);
        //console.log('剩余', scene.children.length, '个')
        dataArr.splice(index, 1);
    }

    _getViewPosi(x, y) {
        const { canvas } = this;
        const [hx, hy] = [canvas.width / 2, canvas.height / 2];
        const [cx, cy] = [
            (x - hx) / hx,
            -(y - hy) / hy,
        ];
        return [cx, cy];
    }

    _draw() {
        const { scene, background_color } = this;
        scene.draw(background_color);
    }

}